#ifndef SCRIPT_HEADER_H
#define SCRIPT_HEADER_H

#include <utility>
#include <vector>

namespace script
{
/**
 * @brief:  错误信息
 * @author: sherlock_lht
 */
class ErrorInfo
{
public:
    int line;                   //错误行
    int column;                 //错误列
    std::string error_message;  //错误描述
    std::string line_code;      //错误所在的行代码
};
enum class TokenType: unsigned char
{
    KeyWord = 0,    //关键字，if/while等
    Identifier,     //标识符，变量名、类型名、字符串内容等
    Punctuator,     //符号，括号、引号等
    Numeric         //数字
};

struct Token
{
    TokenType type;
    std::string token_value;
    int line;
    int column;
};

struct Tokens
{
    std::vector<Token> tokens;
};

static const char *tokenTypeToString(TokenType token_type)
{
    switch (token_type)
    {
        case TokenType::KeyWord:
            return "Key Word";
        case TokenType::Identifier:
            return "Identifier";
        case TokenType::Punctuator:
            return "Punctuator";
        case TokenType::Numeric:
            return "Numeric";
        default:
            return "Unknown token type";
    }
}

enum ASTNodeType: unsigned char
{
    Root = 0,           //语法树根
    VarDeclaration,     //var
    FuncDeclaration,    //function
    IfStatement,        //if
    RepeatStatement,    //repeat
    RetryStatement,     //retry
    WhileLoop,          //while
    Break,              //break
    ReactiveStatement,  //reactive
    ParallelStatement,  //parallel
    ForcePassStatement,  //force pass
    ForceFailStatement,  //force fail
    Identifier,         //标识符，变量名
    Expression,         //表达式
    String,             //字符串
    Numeric,            //数字
    NOT,                //非
    AND,                //与
    OR                  //或
};

static const char *astNodeTypeToString(ASTNodeType type)
{
    switch (type)
    {
        case Root:
            return "root";
        case ASTNodeType::VarDeclaration:
            return "var";
        case ASTNodeType::IfStatement:
            return "if";
        case ASTNodeType::RepeatStatement:
            return "repeat";
        case ASTNodeType::RetryStatement:
            return "retry";
        case ASTNodeType::WhileLoop:
            return "while";
        case ASTNodeType::Break:
            return "break";
        case ASTNodeType::ReactiveStatement:
            return "reactive";
        case ASTNodeType::ParallelStatement:
            return "parallel";
        case ASTNodeType::Identifier:
            return "identifier";
        case ASTNodeType::Expression:
            return "expression";
        case ASTNodeType::String:
            return "string";
        case ASTNodeType::Numeric:
            return "numeric";
        case ASTNodeType::NOT:
            return "not";
        case ASTNodeType::AND:
            return "and";
        case ASTNodeType::OR:
            return "or";
        default:
            return "Unknown token type";
    }
}

struct ASTNode
{
    ASTNodeType type{Root};
    std::string value;
    std::vector<ASTNode> children;
    Token token;

    ASTNode() = default;
    explicit ASTNode(ASTNodeType type)
        : type(type)
    {
    }

    ASTNode(ASTNodeType type, std::string value)
        : type(type), value(std::move(value))
    {
    }
    ASTNode(ASTNodeType type, Token token)
        : type(type), token(std::move(token))
    {
    }
    ASTNode(ASTNodeType type, std::string value, Token token)
        : type(type), value(std::move(value)), token(std::move(token))
    {
    }
};

}

#endif //SCRIPT_HEADER_H
